package com.rainman.simpleredis.demo.config;

import cn.hutool.json.JSONUtil;
import com.rainman.simpleredis.core.SimpleRedis;
import com.rainman.simpleredis.core.config.SimpleDelayWorkDataInterface;
import com.rainman.simpleredis.core.delay_work.SimpleDelayWorkMsgBean;
import com.rainman.simpleredis.core.delay_work.SimpleDelayWorkerInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;


/**
 * 该配置为延迟任务所需配置
 * 若不使用延迟任务，无需配置
 *
 */
@Configuration
public class DelayWorkConfig {


    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    SimpleRedis simpleRedis;

    String RedisDelayWorkOri="DelayWorkOri:";//保存原始数据
    String RedisDelayWorkZSet="DelayWorkZSet";//用于按时间戳排序数据


    /**
     * 延迟任务 生产者需配置。其他不用
     *
     * 延迟任务，持久化配置
     * 该示例是使用redis实现
     * 可以使用关系型数据库实现
     *
     */
    @Bean
    SimpleDelayWorkDataInterface simpleDelayWorkDataInterface(){

        return new SimpleDelayWorkDataInterface() {

            @Override
            public List<SimpleDelayWorkMsgBean> notDealData(Long sTime, Long eTime) {
                //获取时间段内所有未处理的任务的id
                Set<String> delayWorkZSet = stringRedisTemplate.opsForZSet().rangeByScore(RedisDelayWorkZSet, sTime, eTime);
                List<SimpleDelayWorkMsgBean> simpleDelayWorkMsgBeans =new ArrayList<>();
                delayWorkZSet.stream().forEach(id->{
                    //遍历任务id 获取原始数据 返回
                    String s = stringRedisTemplate.opsForValue().get(RedisDelayWorkOri + id);
                    SimpleDelayWorkMsgBean msgBean = JSONUtil.toBean(s, SimpleDelayWorkMsgBean.class);
                    simpleDelayWorkMsgBeans.add(msgBean);

                });
                return simpleDelayWorkMsgBeans;
            }

            @Override
            public void workSure(String id) {//确认时删除原始数据，关系型数据库的话，建议做标记而不是删除

                stringRedisTemplate.opsForZSet().remove(RedisDelayWorkZSet,id);
                stringRedisTemplate.delete(RedisDelayWorkOri+id);

            }


            @Override
            public String addData(SimpleDelayWorkMsgBean msgBean) {

                Long increment = simpleRedis.uniqueIdGetOne();
                msgBean.setId(increment+"");
                stringRedisTemplate.opsForValue().set(RedisDelayWorkOri+msgBean.getId(),JSONUtil.toJsonStr(msgBean));
                stringRedisTemplate.opsForZSet().add(RedisDelayWorkZSet,msgBean.getId(),msgBean.getTigTime());

                return msgBean.getId();
            }

        };

    }

    /**
     *
     * 延迟任务 消费者者需配置。其他不用
     *
     * 延迟任务，处理器
     *
     */
    @Bean
    SimpleDelayWorkerInterface simpleDelayWorkerInterface(){

        return id -> {

            String s = stringRedisTemplate.opsForValue().get(RedisDelayWorkOri + id);
            SimpleDelayWorkMsgBean msgBean = JSONUtil.toBean(s, SimpleDelayWorkMsgBean.class);
            System.out.println("处理延迟任务"+id+new Date());
            System.out.println("处理延迟任务"+msgBean);

            return true;
        };
    }

}
